import axios from 'axios';
import * as vscode from 'vscode';
import fetch, { Response, RequestInit } from 'node-fetch';
import { Readable } from 'stream';

// 添加类型声明
type ReadableStreamDefaultReader<T> = {
    read(): Promise<{ done: boolean; value: T | undefined }>;
    releaseLock(): void;
    cancel(reason?: any): Promise<void>;
};

interface ReadableStream<T = Uint8Array> {
    getReader(): ReadableStreamDefaultReader<T>;
    cancel(reason?: any): Promise<void>;
    locked: boolean;
}

// 首先添加一些类型定义
interface CodebaseAnalysisResponse {
    choices: [{
        message: {
            content: string;
        };
    }];
}

interface APIError extends Error {
    response?: {
        status: number;
    };
}

// 添加类型定义
type SupportedModel = 'deepseek-chat' | 'deepseek-reasoner';

interface ModelInfo {
    name: string;
    description: string;
}

// 使用 type 而不是 interface 来定义映射类型
type SupportedModels = Record<SupportedModel, ModelInfo>;

// 修改思维链相关的类型定义
interface ReasonerResponse {
    id: string;
    object: string;
    created: number;
    model: string;
    choices: [{
        index: number;
        message: {
            role: string;
            content: string;
            reasoning_content?: string;  // R1模型特有的思维链内容
        };
        finish_reason?: string;
        delta?: {
            content?: string;
            reasoning_content?: string;
        };
    }];
    usage?: {
        prompt_tokens: number;
        completion_tokens: number;
        total_tokens: number;
    };
    suggestions?: Array<{
        text: string;
        description: string;
        documentation?: string;
        type?: string;
        insertText?: string;
        sortText?: string;
    }>;
}

// 添加一个通用的响应类型
interface ApiResponse<T = any> {
    id: string;
    object: string;
    created: number;
    model: string;
    choices: Array<T>;
    usage?: {
        prompt_tokens: number;
        completion_tokens: number;
        total_tokens: number;
    };
}

// 添加代码分析响应类型
interface CodeAnalysisResponse extends ApiResponse<{
    message: {
        content: string;
        suggestions?: Array<string>;
    };
}> {}

// 添加代码补全响应类型
interface CompletionResponse extends ApiResponse<{
    message: {
        content: string;
        suggestions?: Array<{
            text: string;
            description: string;
            documentation?: string;
            type?: string;
            insertText?: string;
            sortText?: string;
        }>;
    };
}> {}

export class DeepseekAPI {
    private apiKey: string;
    private baseUrl: string;

    constructor() {
        this.apiKey = vscode.workspace.getConfiguration('deepseek').get('apiKey') || '';
        this.baseUrl = "https://api.deepseek.com";
        
        if (!this.apiKey) {
            vscode.window.showErrorMessage('请先在设置中配置 DeepSeek API Key');
        }
    }

    // 添加验证 API Key 的方法
    public hasValidApiKey(): boolean {
        return !!this.apiKey;
    }

    // 基础聊天功能
    async chat(messages: any[], model: string = "deepseek-chat"): Promise<ReasonerResponse> {
        const response = await fetch(`${this.baseUrl}/v1/chat/completions`, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'Authorization': `Bearer ${this.apiKey}`
            },
            body: JSON.stringify({
                model: model,
                messages: messages,
                // 如果是 R1 模型，添加思维链输出
                ...(model === 'deepseek-reasoner' && {
                    include_reasoning_content: true
                })
            })
        });

        if (!response.ok) {
            throw new Error(`API request failed: ${response.statusText}`);
        }

        return await response.json();
    }

    // 流式聊天
    async chatStream(
        messages: any[], 
        onContent: (content: string, type?: string) => void, 
        signal: AbortSignal, 
        model: string = "deepseek-chat"
    ) {
        try {
            const response = await axios.post(
                `${this.baseUrl}/v1/chat/completions`,
                {
                    model: model,
                    messages: messages,
                    stream: true,  // 确保开启流式输出
                    ...(model === 'deepseek-reasoner' && {
                        include_reasoning_content: true
                    })
                },
                {
                    headers: {
                        'Content-Type': 'application/json',
                        'Authorization': `Bearer ${this.apiKey}`
                    },
                    responseType: 'stream',
                    signal
                }
            );

            return new Promise((resolve, reject) => {
                const stream = response.data as Readable;
                let buffer = '';

                stream.on('data', (chunk: Buffer | string) => {
                    try {
                        const text = chunk.toString();
                        buffer += text;
                        const lines = buffer.split('\n');
                        buffer = lines.pop() || '';

                        for (const line of lines) {
                            if (line.startsWith('data: ')) {
                                const data = line.slice(6);
                                if (data === '[DONE]') continue;

                                try {
                                    const parsed = JSON.parse(data);
                                    // 处理增量内容
                                    const content = parsed.choices[0]?.delta?.content || '';
                                    const reasoningContent = parsed.choices[0]?.delta?.reasoning_content;

                                    if (reasoningContent) {
                                        onContent(reasoningContent, 'reasoning');
                                    }
                                    if (content) {
                                        onContent(content, 'response');
                                    }
                                } catch (e) {
                                    console.error('Error parsing stream data:', e, 'Raw data:', data);
                                }
                            }
                        }
                    } catch (e) {
                        console.error('Error processing stream chunk:', e);
                    }
                });

                stream.on('end', () => {
                    resolve(undefined);
                });

                stream.on('error', (error) => {
                    console.error('Stream error:', error);
                    reject(error);
                });

                signal.addEventListener('abort', () => {
                    stream.destroy();
                    reject(new Error('Stream aborted'));
                });
            });
        } catch (error) {
            console.error('Chat stream error:', error);
            throw error;
        }
    }

    // JSON输出模式
    async chatWithJsonOutput(messages: any[], model: string = "deepseek-chat") {
        const response = await fetch(`${this.baseUrl}/v1/chat/completions`, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'Authorization': `Bearer ${this.apiKey}`
            },
            body: JSON.stringify({
                model: model,
                messages: messages,
                response_format: {
                    type: 'json_object'
                }
            })
        });

        if (!response.ok) {
            throw new Error(`API request failed: ${response.statusText}`);
        }

        return await response.json();
    }

    // Function Calling
    async chatWithFunctions(messages: any[], functions: any[], model: string = "deepseek-chat") {
        const response = await fetch(`${this.baseUrl}/v1/chat/completions`, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'Authorization': `Bearer ${this.apiKey}`
            },
            body: JSON.stringify({
                model: model,
                messages: messages,
                tools: functions
            })
        });

        if (!response.ok) {
            throw new Error(`API request failed: ${response.statusText}`);
        }

        return await response.json();
    }

    // 对话前缀续写(Beta)
    async chatPrefixCompletion(messages: any[], prefix: string, model: string = "deepseek-chat") {
        const response = await fetch(`${this.baseUrl}/beta/chat/completions`, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'Authorization': `Bearer ${this.apiKey}`
            },
            body: JSON.stringify({
                model: model,
                messages: [...messages, {
                    role: "assistant",
                    content: prefix,
                    prefix: true
                }]
            })
        });

        if (!response.ok) {
            throw new Error(`API request failed: ${response.statusText}`);
        }

        return await response.json();
    }

    // FIM补全(Beta)
    async fimCompletion(prompt: string, suffix: string, model: string = "deepseek-chat") {
        const response = await fetch(`${this.baseUrl}/beta/completions`, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'Authorization': `Bearer ${this.apiKey}`
            },
            body: JSON.stringify({
                model: model,
                prompt: prompt,
                suffix: suffix
            })
        });

        if (!response.ok) {
            throw new Error(`API request failed: ${response.statusText}`);
        }

        return await response.json();
    }

    async getCompletions(codeContext: string, linePrefix: string) {
        const messages = [
            { 
                role: 'system', 
                content: `You are a code completion assistant. Provide completion suggestions in JSON format with the following structure:
                {
                    "suggestions": [
                        {
                            "text": "completion text",
                            "description": "brief description",
                            "documentation": "detailed documentation",
                            "type": "function|variable|class|method|property",
                            "insertText": "text to insert (optional)",
                            "sortText": "text for sorting (optional)"
                        }
                    ]
                }`
            },
            { 
                role: 'user', 
                content: `Complete this code based on context:
                Context:
                ${codeContext}
                Current line: ${linePrefix}
                
                Provide 3-5 most relevant completion suggestions.` 
            }
        ];
        
        const response = await this.chat(messages);
        return this.parseCompletionResponse(response);
    }

    async analyzeCode(code: string) {
        const messages = [
            { 
                role: 'system', 
                content: `You are a code refactoring assistant. Analyze code and suggest improvements in JSON format:
                {
                    "refactorings": [
                        {
                            "title": "refactoring title",
                            "description": "detailed description",
                            "type": "performance|readability|security|maintainability",
                            "priority": "high|medium|low",
                            "changes": [
                                {
                                    "file": "file path",
                                    "edits": [
                                        {
                                            "start": number (character offset),
                                            "end": number (character offset),
                                            "newText": "replacement text",
                                            "explanation": "why this change"
                                        }
                                    ]
                                }
                            ]
                        }
                    ]
                }` 
            },
            { 
                role: 'user', 
                content: `Analyze and suggest refactoring for this code:\n${code}
                
                Focus on:
                1. Code structure and organization
                2. Performance improvements
                3. Best practices
                4. Potential bugs
                5. Security issues` 
            }
        ];
        
        const response = await this.chat(messages);
        return this.parseRefactoringResponse(response);
    }

    async suggestCodeChanges(code: string) {
        // 实现代码改进建议逻辑
        const messages = [
            { role: 'system', content: 'You are a code improvement assistant.' },
            { role: 'user', content: `Please suggest improvements for this code:\n${code}` }
        ];
        return this.chat(messages);
    }

    // 改进代码片段生成，使用 DeepSeek-R1 推理模型
    async generateCodeSnippet(description: string, language: string, context?: string) {
        const messages = [
            {
                role: 'system',
                content: `You are a code snippet generator specialized in ${language}. 
                Generate code that follows best practices and includes proper error handling.
                Use DeepSeek's Function Calling feature to structure the response.`
            },
            {
                role: 'user',
                content: `Generate a code snippet for: ${description}
                ${context ? `Context:\n${context}` : ''}
                Requirements:
                1. Follow ${language} best practices
                2. Include error handling
                3. Add proper comments
                4. Make it reusable
                5. Consider performance`
            }
        ];

        const response = await axios.post(
            `${this.baseUrl}/chat/completions`,
            {
                messages,
                model: 'deepseek-reasoner',  // 使用 DeepSeek-R1 推理模型
                temperature: 0.3,  // 降低随机性以获得更稳定的输出
                max_tokens: 2000,
                functions: [
                    {
                        name: "generate_code_snippet",
                        description: "Generate a code snippet with metadata",
                        parameters: {
                            type: "object",
                            properties: {
                                prefix: {
                                    type: "string",
                                    description: "Snippet trigger word"
                                },
                                description: {
                                    type: "string",
                                    description: "Snippet description"
                                },
                                body: {
                                    type: "array",
                                    items: {
                                        type: "string"
                                    },
                                    description: "Code lines"
                                },
                                variables: {
                                    type: "array",
                                    items: {
                                        type: "object",
                                        properties: {
                                            name: { type: "string" },
                                            description: { type: "string" }
                                        }
                                    },
                                    description: "Snippet variables"
                                }
                            },
                            required: ["prefix", "description", "body"]
                        }
                    }
                ],
                function_call: { name: "generate_code_snippet" }
            },
            {
                headers: {
                    'Authorization': `Bearer ${this.apiKey}`,
                    'Content-Type': 'application/json',
                }
            }
        );

        return response.data;
    }

    private parseCompletionResponse(response: any): any {
        try {
            const lines = response.choices[0].message.content
                .split('\n')
                .filter((line: string) => line.trim())
                .map((line: ParsedLine) => ({
                    type: 'suggestion',
                    content: line.content
                }));
            return {
                suggestions: lines.map((line: ParsedLine) => ({
                    text: line.content,
                    description: '代码补全建议',
                    documentation: '由 DeepSeek 提供的代码补全',
                    type: line.type || 'snippet',
                    insertText: line.content,
                    sortText: line.content
                }))
            };
        } catch (error) {
            console.warn('Falling back to simple completion parsing:', error);
            return {
                suggestions: response.choices[0].message.content
                    .split('\n')
                    .filter((line: string) => line.trim())
                    .map((line: string) => ({
                        text: line.trim(),
                        description: '代码补全建议',
                        documentation: '由 DeepSeek 提供的代码补全',
                        type: 'snippet',
                        insertText: line.trim(),
                        sortText: line.trim()
                    }))
            };
        }
    }

    private parseRefactoringResponse(response: any) {
        const content = response.choices[0].message.content;
        try {
            // 尝试解析 JSON 响应
            const parsed = JSON.parse(content);
            return {
                refactorings: parsed.refactorings.map((refactoring: any) => ({
                    title: refactoring.title,
                    description: refactoring.description,
                    type: refactoring.type || 'readability',
                    priority: refactoring.priority || 'medium',
                    changes: refactoring.changes.map((change: any) => ({
                        file: change.file,
                        edits: change.edits.map((edit: any) => ({
                            start: edit.start,
                            end: edit.end,
                            newText: edit.newText,
                            explanation: edit.explanation
                        }))
                    }))
                }))
            };
        } catch (error) {
            // 如果 JSON 解析失败，返回简单的文本描述
            console.warn('Falling back to simple refactoring parsing:', error);
            return {
                refactorings: [{
                    title: '代码改进建议',
                    description: content,
                    type: 'readability',
                    priority: 'medium',
                    changes: []
                }]
            };
        }
    }

    async getSuggestionFix(code: string, start: number, end: number): Promise<{ newText: string } | null> {
        const messages = [
            {
                role: 'system',
                content: 'You are a code fix suggestion assistant. Provide specific fixes for code issues.'
            },
            {
                role: 'user',
                content: `Fix this code section (positions ${start}-${end}):\n${code}`
            }
        ];

        try {
            const response = await this.chat(messages);
            const suggestion = response.choices[0].message.content;
            return { newText: suggestion.trim() };
        } catch (error) {
            console.error('Error getting fix suggestion:', error);
            return null;
        }
    }

    async analyzeCodebase(data: {
        files: { path: string; content: string }[];
        overview: { path: string; size: number; type: string }[];
    }): Promise<CodebaseAnalysisResponse> {
        try {
            // 准备发送给 API 的消息
            const messages = [
                {
                    role: 'system',
                    content: `你是一个代码分析助手。请分析提供的代码库并提供以下信息：
                    1. 项目结构分析
                    2. 主要功能和模块
                    3. 代码质量评估
                    4. 潜在问题和改进建议
                    5. 依赖关系分析
                    请用中文回答，并使用 Markdown 格式。`
                },
                {
                    role: 'user',
                    content: `请分析以下代码库：

文件概览：
${data.overview.map(f => `- ${f.path} (${f.type}, ${f.size} bytes)`).join('\n')}

代码内容：
${data.files.map(f => `
=== ${f.path} ===
${f.content}
`).join('\n')}

请提供详细的分析报告。`
                }
            ];

            // 直接使用 chat/completions 接口
            const response = await axios.post(
                `${this.baseUrl}/chat/completions`,
                {
                    model: 'deepseek-chat',
                    messages: messages,
                    temperature: 0.7,
                    max_tokens: 4000,
                    stream: false
                },
                {
                    headers: {
                        'Authorization': `Bearer ${this.apiKey}`,
                        'Content-Type': 'application/json',
                    }
                }
            );

            // 检查响应数据
            console.log('API Response:', response.data);

            if (!response.data || !response.data.choices || !response.data.choices[0]) {
                throw new Error('Invalid API response format');
            }

            // 返回分析结果
            return {
                choices: [{
                    message: {
                        content: response.data.choices[0].message?.content || '分析失败，请重试'
                    }
                }]
            };
        } catch (error: unknown) {
            console.error('Codebase analysis error:', error);
            
            const apiError = error as APIError;
            
            if (apiError.response?.status === 400) {
                console.log('Received 400 error, trying with truncated data');
                // 尝试减少发送的数据量
                const truncatedFiles = data.files.map(f => ({
                    path: f.path,
                    content: f.content.length > 1000 ? 
                        f.content.substring(0, 1000) + '...(truncated)' : 
                        f.content
                }));

                // 重试一次，使用截断的数据
                return this.analyzeCodebase({
                    files: truncatedFiles,
                    overview: data.overview
                });
            }

            // 如果是其他错误，返回一个友好的错误消息
            return {
                choices: [{
                    message: {
                        content: `分析过程中出现错误：${apiError.message || '未知错误'}`
                    }
                }]
            };
        }
    }

    async getCompletionsWithCodebase(
        codeContext: string,
        linePrefix: string,
        codebaseContext: any,
        language: string
    ) {
        const messages = [
            { 
                role: 'system', 
                content: `You are a code completion assistant with knowledge of the entire codebase. 
                Provide completion suggestions in JSON format with the following structure:
                {
                    "suggestions": [
                        {
                            "text": "completion text",
                            "description": "brief description",
                            "documentation": "detailed documentation with codebase context",
                            "type": "function|variable|class|method|property",
                            "insertText": "text to insert (optional)",
                            "sortText": "text for sorting (optional)"
                        }
                    ]
                }
                Consider the codebase context when making suggestions.`
            },
            {
                role: 'user',
                content: `Codebase context:
                ${JSON.stringify(codebaseContext, null, 2)}

                Current file context:
                Language: ${language}
                Previous code:
                ${codeContext}
                Current line: ${linePrefix}
                
                Provide 3-5 most relevant completion suggestions that align with the codebase patterns and conventions.`
            }
        ];
        
        const response = await this.chat(messages);
        return this.parseCompletionResponse(response);
    }
}

// 添加类型定义
interface ParsedLine {
    type: string;
    content: string;
} 